package com.bootdo.check.service.impl;

import java.io.File;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bootdo.check.dao.VideoDao;
import com.bootdo.check.domain.DetectResult;
import com.bootdo.check.domain.VideoDO;
import com.bootdo.check.service.ColorLogo;
import com.bootdo.check.service.DetectService;
import com.bootdo.common.utils.SpringContextHolder;

/**
 * 视频检测模块
 * 
 * @author ke
 *
 */
@Service
public class DetectServiceImpl implements DetectService {

	@Autowired
	private VideoDao videoDao;

	private static final CompletionService<DetectResult> completionService = new ExecutorCompletionService<>(
			Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()));

	private static final Logger logger = LoggerFactory.getLogger(DetectServiceImpl.class);

//	@Resource(name = ColorLogo.BLACK)
	private ColorLogo colorBlack;

//	@Resource(name = ColorLogo.WHITE)
	private ColorLogo colorWhite;

	@Override
	public void detect(String path, int id) {
		File file = new File(path);
		if (!file.exists()) {
			updateResult("视频不存在", "检测异常", id);
			return;
		}
		try {
			completionService.submit(new Matcher(file, id, colorBlack));
			updateResult("检测中", "检测中", id);
		} catch (org.bytedeco.javacv.FrameGrabber.Exception e) {
			// 数据库存储任务提交失败
			updateResult("帧抓取异常", "检测异常", id);
			logger.error(e.getMessage(), e);

		}

	}

//	@PostConstruct
	public void doCheck() {

		Thread thread = new Thread(() -> {
			while (true) {
				try {
					DetectResult detectResult = completionService.take().get();
					if (detectResult != null) {
						if (detectResult.getFile().getAbsolutePath().contains("junshi")) {
							updateResult(detectResult);
							continue;
						}
						// 对完全不合格视频做二次确认
						if (detectResult.getLogoLoaction() == 0 && !detectResult.isHasHead()
								&& !detectResult.isHasTail()
								&& videoDao.get(detectResult.getId()).getChekcResult().contains("检测中")) {
							douleCheck(detectResult);
							continue;
						}
						// 存储检测结果
						updateResult(detectResult);
					}
				} catch (InterruptedException e) {
					Thread.currentThread().interrupt();
					logger.error(e.getMessage(), e);
				} catch (ExecutionException e) {
					logger.error(e.getMessage(), e);
				}
			}

		});
		thread.setDaemon(true);
		thread.start();

	}

	private void douleCheck(DetectResult detectResult) {
		updateResult("二次检测中", "检测中", detectResult.getId());
		try {
			completionService.submit(new Matcher(detectResult.getFile(), detectResult.getId(), colorWhite));
		} catch (org.bytedeco.javacv.FrameGrabber.Exception e) {
			logger.error("二次检测失败=>{}", e.getMessage(), e);
			updateResult("二次检测失败", "检测异常", detectResult.getId());
		}
	}

	private void updateResult(String checkResult, String status, int id) {
		VideoDO videoDO = new VideoDO();
		videoDO.setIdvideo(id);
		videoDO.setChekcResult(checkResult);
		videoDO.setStatus(status);
		videoDao.update(videoDO);
	}

	private void updateResult(DetectResult detectResult) {
		StringBuilder sb = new StringBuilder();
		sb.append("科协logo位置：");
		switch (detectResult.getLogoLoaction()) {
		case 0:
			sb.append("未检出，");
			break;
		case 1:
			sb.append("左上角，");
			break;
		case 2:
			sb.append("左下角，");
			break;
		case 3:
			sb.append("右下角，");
			break;
		case 4:
			sb.append("右上角，");
			break;
		default:
			break;
		}
		sb.append(detectResult.isHasHead() ? "科协片头：有，" : "科协片头：无，").append(detectResult.isHasTail() ? "片尾：有" : "片尾：无");
		VideoDO videoDO = new VideoDO();
		videoDO.setIdvideo(detectResult.getId());
		String checkResult = sb.toString();
		videoDO.setChekcResult(checkResult);
		if (checkResult.contains("无") || checkResult.contains("未检出")) {
			videoDO.setStatus("检测不合格");
		} else {
			videoDO.setStatus("检测合格");
		}
		videoDao.update(videoDO);
	}

}
